﻿using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.Text;
using SourceGeneratorInterface;
using System.Collections.Immutable;
using System.Linq;
using System.Text;

namespace SourceGeneratorLibrary
{
    [Generator]
    public class AutoDependencyInjectionGenerator : IIncrementalGenerator
    {
        public void Initialize(IncrementalGeneratorInitializationContext context)
        {
            // 1. 注册接口代码
            //            context.RegisterPostInitializationOutput(ctx =>
            //            {
            //                const string interfaceSource = @"// <auto-generated />
            //namespace SourceGeneratorLibrary
            //{
            //    /// <summary>
            //    /// 标记类为 Scoped 生命周期的依赖注入
            //    /// </summary>
            //    public interface IScopedDependency
            //    {
            //    }

            //    /// <summary>
            //    /// 标记类为 Singleton 生命周期的依赖注入
            //    /// </summary>
            //    public interface ISingletonDependency
            //    {
            //    }

            //    /// <summary>
            //    /// 标记类为 Transient 生命周期的依赖注入
            //    /// </summary>
            //    public interface ITransientDependency
            //    {
            //    }
            //}";
            //                ctx.AddSource("DependencyInterfaces.g.cs",
            //                    SourceText.From(interfaceSource, Encoding.UTF8));
            //            });

            // 2. 创建管道：筛选实现了依赖注入接口的类
            var classDeclarations = context.SyntaxProvider
                .CreateSyntaxProvider(
                    predicate: static (s, _) => IsCandidateClass(s),
                    transform: static (ctx, _) => GetSemanticTargetForGeneration(ctx))
                .Where(static m => m is not null);

            // 3. 收集编译信息和类声明
            var compilationAndClasses = context.CompilationProvider.Combine(classDeclarations.Collect());

            // 4. 生成代码
            context.RegisterSourceOutput(compilationAndClasses,
                static (spc, source) => Execute(source.Left, source.Right, spc));
        }

        // 快速筛选：是否为实现了接口的类
        private static bool IsCandidateClass(SyntaxNode node)
        {
            return node is ClassDeclarationSyntax classDeclaration &&
                   classDeclaration.BaseList?.Types.Count > 0;
        }

        // 语义分析：获取符号信息和生命周期类型
        private static ClassInfo GetSemanticTargetForGeneration(GeneratorSyntaxContext context)
        {
            var classDeclaration = (ClassDeclarationSyntax)context.Node;
            var symbol = context.SemanticModel.GetDeclaredSymbol(classDeclaration);

            if (symbol is not INamedTypeSymbol classSymbol || classSymbol.IsAbstract)
                return null;

            // 检查类实现的接口
            var interfaces = classSymbol.AllInterfaces;
            ServiceLifetime? lifetime = null;

            foreach (var iface in interfaces)
            {
                var interfaceName = iface.Name;

                if (interfaceName == nameof(IScopedDependency))
                {
                    lifetime = ServiceLifetime.Scoped;
                    break;
                }
                else if (interfaceName == nameof(ISingletonDependency))
                {
                    lifetime = ServiceLifetime.Singleton;
                    break;
                }
                else if (interfaceName == nameof(ITransientDependency))
                {
                    lifetime = ServiceLifetime.Transient;
                    break;
                }
            }

            if (lifetime.HasValue)
            {
                return new ClassInfo(classSymbol, lifetime.Value);
            }

            return null;
        }

        // 生成扩展方法代码
        private static void Execute(Compilation compilation, ImmutableArray<ClassInfo> classes, SourceProductionContext context)
        {
            if (classes.IsDefaultOrEmpty)
                return;

            // 按生命周期分组
            var scopedClasses = classes.Where(c => c.Lifetime == ServiceLifetime.Scoped).Select(c => c.Symbol).Distinct().ToList();
            var singletonClasses = classes.Where(c => c.Lifetime == ServiceLifetime.Singleton).Select(c => c.Symbol).Distinct().ToList();
            var transientClasses = classes.Where(c => c.Lifetime == ServiceLifetime.Transient).Select(c => c.Symbol).Distinct().ToList();

            // 构建服务注册代码
            var registrations = new StringBuilder();
            const string indent = "            ";

            // 注册 Scoped 服务
            foreach (var classSymbol in scopedClasses)
            {
                var fullTypeName = classSymbol.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat);
                registrations.AppendLine($"{indent}services.AddScoped<{fullTypeName}>();");
            }

            // 注册 Singleton 服务
            foreach (var classSymbol in singletonClasses)
            {
                var fullTypeName = classSymbol.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat);
                registrations.AppendLine($"{indent}services.AddSingleton<{fullTypeName}>();");
            }

            // 注册 Transient 服务
            foreach (var classSymbol in transientClasses)
            {
                var fullTypeName = classSymbol.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat);
                registrations.AppendLine($"{indent}services.AddTransient<{fullTypeName}>();");
            }

            if (registrations.Length == 0)
                return;

            // 生成扩展类
            var safeAssemblyName = compilation.AssemblyName?
                .Replace(".", "_")
                .Replace("-", "_") ?? "Generated";

            var extensionCode = $@"// <auto-generated />
using Microsoft.Extensions.DependencyInjection;

namespace SourceGeneratorLibrary
{{
    public static partial class GeneratedServicesExtension
    {{
        public static IServiceCollection AddServicesIn{safeAssemblyName}(this IServiceCollection services)
        {{
            return services.AddGeneratedServices();
        }}

        internal static IServiceCollection AddGeneratedServices(this IServiceCollection services)
        {{
{registrations}            return services;
        }}
    }}
}}";

            context.AddSource($"GeneratedServicesExtension_{safeAssemblyName}.g.cs",
                SourceText.From(extensionCode, Encoding.UTF8));
        }

        // 辅助类：存储类信息和生命周期
        private class ClassInfo
        {
            public INamedTypeSymbol Symbol { get; }
            public ServiceLifetime Lifetime { get; }

            public ClassInfo(INamedTypeSymbol symbol, ServiceLifetime lifetime)
            {
                Symbol = symbol;
                Lifetime = lifetime;
            }
        }

        // 服务生命周期枚举
        private enum ServiceLifetime
        {
            Scoped,
            Singleton,
            Transient
        }
    }
}
